/**
 * type: string
 * pageName: string
 * data: array
 * path: array
 *
 * add:{
 *  type:"add" //添加组件
 *  pageName: //页面名称
 *  data: [组件数据, 序号]
 *  path: [新组件路径]
 * }
 *
 * delete:{
 *  type:"delete" //删除组件
 *  pageName: //页面名称
 *  data: [组件数据, 序号]
 *  path: //被删除组件路径
 * }
 *
 * moveBox:{
 *  type:"moveBox" //组件从一个容器移动到另一个
 *  pageName: //页面名称
 *  data: [旧数据，新数据]
 *  path: [旧路径，新路径]
 * }
 *
 * attrsChange:{
 *  type:"attrsChange" //组件样式变化
 *  pageName: //页面名称
 *  data: [旧数据，新数据]
 *  path: [组件路径]
 * }
 *
 * sortChange:{
 *  type:"sortChange" //组件顺序上下移动
 *  pageName: //页面名称
 *  data: [原来序号，up或down]
 *  path: //组件路径
 * }
 */
// type:cancel/restore
interface State {
  aimDom: {
    style?: { [organName: string]: string };
    context?: { value: string; type: string };
    faPosition?: { top: number; left: number };
    [organName: string]: any;
  }; //目标DOM节点
  aimPath: {}[]; //目标路径
  aimAttrs: {
    context?: string;
    goto?: { type: string; value: string };
    [organName: string]: any;
  }; //目标属性
  aimBox: {} | null; //目标容器
  aimXY: {} | null; //鼠标与组件的偏移
  componentList: { [organName: string]: {} };
  seniorBoxList: { [organName: string]: {} };
  //为了可以显示margin...
  colorDomStyle: {
    width: string;
    height: string;
    top: string;
    left: string;
    padding: string;
    border: string;
    margin: string;
  };
  judgeColorDom: boolean;
  domStack: {
    type: string;
    pageName: string;
    data: (string | number | {})[];
    path: {}[][];
  }[]; //存储栈
  domStackNum: number; //存储栈控制下标
  page?: {
    tree: {
      [organName: string]: {}[];
    };
  };
}

export default function(
  state: State,
  {
    that,
    type,
  }: {
    that: {
      $searchDom: Function;
    };
    type: string;
  }
) {
  if (type == "cancel") {
    let domOperation = state.domStack[state.domStackNum];
    if (domOperation.type == "add") {
      // 如果是添加组件
      // 把它删除了
      that.$searchDom(
        state.page?.tree[domOperation.pageName],
        domOperation.path[0],
        true
      );
    } else if (domOperation.type == "delete") {
      // 如果是删除组件
      if (domOperation.path.length == 1) {
        // 是在根节点下
        // 直接添加组件
        state.page?.tree[domOperation.pageName].splice(
          domOperation.data[1] as number,
          0,
          JSON.parse(JSON.stringify(domOperation.data[0]))
        );
      } else {
        // 要找被删除组件的父节点才行
        let faDom = that.$searchDom(
          state.page?.tree[domOperation.pageName],
          domOperation.path.slice(0, -1),
          false
        );
        // 在父节点下添加
        faDom.children.push(JSON.parse(JSON.stringify(domOperation.data[0])));
      }
    } else if (domOperation.type == "moveBox") {
      //跨容器移动
      //先删除原来的通用组件
      that.$searchDom(
        state.page?.tree[domOperation.pageName],
        domOperation.path[1],
        true
      );
      // 再找到父节点
      let tree = that.$searchDom(
        state.page?.tree[domOperation.pageName],
        domOperation.path[0].slice(0, -1),
        false
      );
      // 在父节点下添加
      tree.children.push(JSON.parse(JSON.stringify(domOperation.data[0])));
    } else if (domOperation.type == "attrsChange") {
      //样式变化
      if (domOperation.path[0].length == 1) {
        //如果数组为2，即是页面的根节点
        // 直接找，然后进行替换
        if (state.page) {
          state.page.tree[domOperation.pageName] = state.page.tree[
            domOperation.pageName
          ].map((item: any) => {
            let dom = domOperation.data[0] as { attrs: { class: string } };
            if (item.attrs.class == dom.attrs.class) {
              return (item = domOperation.data[0]);
            }
            return item;
          });
        }
      } else {
        // 要找到父节点先
        let dom = that.$searchDom(
          state.page?.tree[domOperation.pageName],
          domOperation.path[0].slice(0, -1),
          false
        );
        // 然后进行替换
        dom.children = dom.children.map((item: any) => {
          let dom = domOperation.data[0] as { attrs: { class: string } };
          if (item.attrs.class == dom.attrs.class) {
            return domOperation.data[0];
          }
          return item;
        });
        // console.log(dom);
      }
    } else if (domOperation.type == "sortChange") {
      //组件顺序上下移动
      let tree = state.page?.tree[domOperation.pageName] as []; //发生变化的页面
      if (!tree) return;
      if (domOperation.data[1] == "up") {
        // 上升--就是把变化的两个进行调换
        //序号
        let value = domOperation.data[0] as number;
        let obj = tree[value]; //找到组件
        tree[value] = tree[value - 1];
        tree[value - 1] = obj;
      } else {
        // 下降--就是把变化的两个进行调换
        let value = domOperation.data[0] as number;
        let obj = tree[value];
        tree[value] = tree[value + 1];
        tree[value + 1] = obj;
      }
    }

    // console.log(domOperation.type);
    state.domStackNum -= 1; //下标减一
  } else if (type == "restore") {
    let domOperation: {
      type: string;
      pageName: string;
      data: (string | number | {})[];
      path: {}[][];
    }; //变化数据

    state.domStackNum += 1;
    domOperation = state.domStack[state.domStackNum]; //取出数据

    if (domOperation.type == "add") {
      //如果数组为2，即是页面的根节点
      if (domOperation.path[0].length == 1) {
        //直接再对应的下标添加组件即可
        state.page?.tree[domOperation.pageName].splice(
          domOperation.data[1] as number,
          0,
          JSON.parse(JSON.stringify(domOperation.data[0]))
        );
      } else {
        //要通过searchDom进行父组件查找
        let dom = that.$searchDom(
          state.page?.tree[domOperation.pageName],
          domOperation.path[0].slice(0, -1),
          false
        );
        // 然后进行添加
        dom.children.push(domOperation.data[0]);
      }
    } else if (domOperation.type == "delete") {
      //直接删除，不BB
      that.$searchDom(
        state.page?.tree[domOperation.pageName],
        domOperation.path[0],
        true
      );
    } else if (domOperation.type == "moveBox") {
      // 组件移动
      // 先删除原来的组件
      that.$searchDom(
        state.page?.tree[domOperation.pageName],
        domOperation.path[0],
        true
      );
      // 找到新的父组件
      let tree = that.$searchDom(
        state.page?.tree[domOperation.pageName],
        domOperation.path[1].slice(0, -1), //删除变化组件的路径
        false
      );
      // console.log(tree);
      // 在下面添加
      tree.children.push(JSON.parse(JSON.stringify(domOperation.data[1])));
    } else if (domOperation.type == "attrsChange") {
      //如果数组为2，即是页面的根节点
      // 直接找到对应的组件，把新数据赋值
      if (domOperation.path[0].length == 1) {
        if (state.page) {
          state.page.tree[domOperation.pageName] = state.page.tree[
            domOperation.pageName
          ].map((item: any) => {
            let dom = domOperation.data[1] as { attrs: { class: string } };
            if (item.attrs.class == dom.attrs.class) {
              return (item = domOperation.data[1]);
            }
            return item;
          });
        }
      } else {
        // 找爸爸组件
        let dom = that.$searchDom(
          state.page?.tree[domOperation.pageName],
          domOperation.path[0].slice(0, -1),
          false
        );
        // 找儿子组件--赋值
        dom.children = dom.children.map((item: any) => {
          let dom = domOperation.data[1] as { attrs: { class: string } };
          if (item.attrs.class == dom.attrs.class) {
            return domOperation.data[1];
          }
          return item;
        });
        // console.log(dom);
      }
    } else if (domOperation.type == "sortChange") {
      // 和上面相反
      let tree = state.page?.tree[domOperation.pageName];
      if (!tree) return;
      if (domOperation.data[1] == "up") {
        let value = domOperation.data[0] as number;
        let obj = tree[value];
        tree[value] = tree[value - 1];
        tree[value - 1] = obj;
      } else {
        let value = domOperation.data[0] as number;
        let obj = tree[value];
        tree[value] = tree[value + 1];
        tree[value + 1] = obj;
      }
    }
    // console.log(domOperation.type);
  }
  // 将数据清空
  state.aimDom = {};
  state.aimAttrs = {};
  state.aimPath = [];
}
